package org.thalien.roleplay.logic;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.slf4j.Logger;

import com.google.inject.Inject;

public abstract class AbstractDao<T> {
	
	@Inject
	private EntityManager em;
	
	protected abstract Logger getLogger();
	
	public abstract Class<T> getEntityClass();
	
	public abstract Object getId(T entity);
	
	public EntityManager getEntityManager() {
		return this.em;
	}
	
	public T save(T entity) throws LogicException {
		if (entity == null) return null;
		em.getTransaction().begin();
		try {
			if (this.getId(entity) == null) {
				em.persist(entity);
			} else {
				//em.find(this.getEntityClass(), entity);
				entity = em.merge(entity);
			}
			em.getTransaction().commit();
			return entity;
		} catch (Exception e) {
			em.getTransaction().rollback();
			throw new LogicException(e);
		}
	}
	
	public void delete(T entity) throws LogicException {
		if (entity == null || this.getId(entity) == null) {
			return;
		}
		try {
			em.getTransaction().begin();
			em.remove(entity);
			em.getTransaction().rollback();
		} catch (Exception e) {
			em.getTransaction().rollback();
			throw new LogicException(e);
		}		
	}
	
	@SuppressWarnings("unchecked")
	public List<T> getAllEntities() {
		String query = "select O from "+this.getEntityClass().getSimpleName()+" O";
		return em.createQuery(query).getResultList();
	}
	
	public T findById(Object id) {
		return em.find(this.getEntityClass(), id);
	}
	
	protected T findByName(String name) {
		if (name == null || name.trim().length() == 0) return null;
		
		String queryString = "select O from "+this.getEntityClass().getSimpleName()+" O where O.name = :name";
		Query query = em.createQuery(queryString);
		query.setParameter("name", name);
		
		@SuppressWarnings("unchecked")
		List<T> entities = query.getResultList();
		
		if (entities.size() == 1) {
			return entities.get(0);
		}
		return null;
	}
}
